/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Facades;

import Clases.Curso;
import Clases.CursoPractica;
import Clases.Perfil;
import Clases.Practica;
import Clases.TipoUsuario;
import Clases.Usuario;
import Clases.UsuarioCurso;
import Clases.UsuarioPractica;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManager;

/**
 *
 * @author pablo
 */
public abstract class AbstractFacade<T> {
    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0] + 1);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }
    
    //Codigo
    
    public Usuario usuarioLogin(Usuario usr){
        
        List lista = getEntityManager().createNamedQuery("Usuario.findByLogin")
                .setParameter("nombre", usr.getNombre())
                .setParameter("password", usr.getPassword())
                .getResultList();
        
        if(lista.size() > 0){
            Iterator it = lista.iterator();
            while(it.hasNext())
                return (Usuario) it.next();
        }
        return null;
    }
    
    public Perfil usuarioToPerfil(Usuario usr){
        List lista = getEntityManager().createNamedQuery("Perfil.findByIdusuario")
                .setParameter("idusuario", usr.getIdPerfilFK().getIdPerfil())
                .getResultList();
                
        if(lista.size() > 0){
            Iterator it = lista.iterator();
            while(it.hasNext())
                return (Perfil) it.next();
        }
        return null;
    }
    
    public List listaPracticas(Curso cr){
        ArrayList<Practica> lista2 = new ArrayList<>();
        List lista = getEntityManager().createNamedQuery("Cursopractica.findAllByIdCursoFK")
                .setParameter("idcursofk", cr)
                .getResultList();
        
        if(lista.size() > 0){
            Iterator it = lista.iterator();
            while(it.hasNext()){
                CursoPractica cp = (CursoPractica) it.next();
                List lista3 = getEntityManager().createNamedQuery("Practica.findByIdPractica")
                .setParameter("idpractica", cp.getIdPracticaFK().getIdPractica())
                .getResultList();
                
                if(lista3.size() > 0){
                    Iterator it2 = lista3.iterator();
                    while(it2.hasNext())
                        lista2.add((Practica) it2.next());
                }
            }
        }
        return lista2;
    }
    
    public ArrayList<Curso> cursoUsuario(Usuario usr){
        ArrayList<Curso> lista = new ArrayList<>();
        List lista2 = getEntityManager().createNamedQuery("UsuarioCurso.findByUsuario")
                .setParameter("idusuariofk", usr)
                .getResultList();
        
        if(lista2.size() > 0){
            Iterator it = lista2.iterator();
            while(it.hasNext()){
                UsuarioCurso uc = (UsuarioCurso) it.next();
                List lista3 = getEntityManager().createNamedQuery("Curso.findByIdCurso")
                        .setParameter("idCurso", uc.getIdCursoFK().getIdCurso())
                        .getResultList();
                
                if(lista3.size() > 0){
                    Iterator it2 = lista3.iterator();
                    while(it2.hasNext())
                        lista.add((Curso) it2.next());
                }
            }
        }       
        return lista;
    }
    
    public ArrayList<Practica> practicaFechaNoExpirada(ArrayList<Curso> listaCursos){
        ArrayList<Practica> lista = new ArrayList<>();
        java.util.Date fecha = new Date();
        
        if (listaCursos.size() > 0){
            Iterator it = listaCursos.iterator();
            while (it.hasNext()){
                List l = this.listaPracticas((Curso) it.next());
                if(l.size() > 0){
                    Iterator it2 = l.iterator();
                    while(it2.hasNext()){
                        Practica p = (Practica) it2.next();
                        if(p.getFechaFin().after(fecha))
                            lista.add(p);
                    }
                }
            }
        }
        return lista;
    }
    
    public ArrayList<Practica> practicaFechaNoExpiradaPorCurso(Curso cr){
        ArrayList<Curso> lista2 = new ArrayList<>();        
        lista2.add(cr);        
        return practicaFechaNoExpirada(lista2);        
    }
    
    public String notaAlumnoPractica(Usuario usr, Practica pr){
        String nota = "-"; 
        List lista = getEntityManager().createNamedQuery("UsuarioPractica.findByUsuarioAndPractica")
                .setParameter("idpracticafk", pr)
                .setParameter("idusuariofk", usr)
                .getResultList();
        
        if(lista.size() > 0){
            Iterator it = lista.iterator();
            while(it.hasNext()){
                UsuarioPractica up = (UsuarioPractica) it.next();
                nota = up.getNota().toString();
            }
        }
        return nota;
    }
    
    public List alumnosPracticaEntregada(Practica pr){
        //Con esto obtenemos que alumnos han entregado la practica
        List lista = getEntityManager().createNamedQuery("UsuarioPractica.findByPracticaFK")
                .setParameter("idpracticaFK", pr)
                .getResultList();

        return lista;
    }
    
    public List alumnosPracticaEntregadaDist(Practica pr){
        //Con esto obtenemos que alumnos han entregado la practica
        List lista = getEntityManager().createNamedQuery("UsuarioPractica.findByPracticaFKDist")
                .setParameter("idpracticaFK", pr)
                .getResultList();

        return lista;
    }
    
    public boolean practicaSubidaAlumno(Practica pra, Usuario usr){
        return !"-".equals(notaAlumnoPractica(usr,pra));
    }
    
    
    public List notaPorAlumno(Practica pr, Usuario usr){
       //Con esto obtenemos que alumnos han entregado la practica
        List lista = getEntityManager().createNamedQuery("UsuarioPractica.findByPracticaFKANDUsuarioFKt")
                .setParameter("idpracticaFK", pr)
                .setParameter("idUsuarioFK", usr)
                .getResultList();

        return lista;
    }
    
    public ArrayList<TipoUsuario> tiposUsuarios(){
        return (ArrayList<TipoUsuario>) getEntityManager().createNamedQuery("TipoUsuario.findAll");
    }
    //Codigo
}
